/**
 *******************************************************************************
 * @brief       Provide a brief description of the module here (Single line).
 * 
 * @author      Ashwin
 * 
 * @file        Eep.c
 * 
 * @version
 * 
 * @date        Feb 18, 2012 6:27:35 PM
 * 
 * @details     Provide a detailed description of the module here (Multi-line).
 * 
 * @pre         Mention any preconditions required to use this module.
 * 
 * @bug         List any bugs in this module.
 * 
 * @note        List any odd modes while using this module.
 * 
 * @warning     List any warnings against using the objects of this module.
 *******************************************************************************
 * @copyright 2012
 * <a href="http://www.afflatustech.com">Afflatus Techtronics</a>
 * and <a href="http://www.ashwinvijayakumar.co.nr">Ashwin Vijayakumar</a>
 * @n@n
 * This work is licensed under the Creative Commons
 * Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy
 * of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or
 * send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain
 * View, California, 94041, USA.
 *******************************************************************************
 */

/**@cond -----------------------------------------------------------------------
 * Includes section
 * Add all #include here.
 * ----------------------------------------------------------------- @endcond */

/**@cond System headers -------------------------------------------- @endcond */
#include <i2c.h>
#include <string.h>
#include <delays.h>

/**@cond Local headers --------------------------------------------- @endcond */
#include "Eep.h"
#include "Std_Types.h"

/**@cond -----------------------------------------------------------------------
 * typedef section (File scope)
 * Add typedef's with file scope here.
 * Capitalization: Upper_Camel_Case.
 * Declare typedef's with project scope in Eep.h.
 * ----------------------------------------------------------------- @endcond */

/**@cond -----------------------------------------------------------------------
 * Constants section (File scope)
 * Add all constants with file scope here.
 * Capitalization: ALL_CAPS.
 * Note that all constants listed here are limited to this file scope.
 * For project wide scope, declare constants in Eep.h.
 * ----------------------------------------------------------------- @endcond */

#define EEP_READ_WRITE_MSK      0x01

/**@cond -----------------------------------------------------------------------
 * Macros section (File scope)
 * Add all macros with file scope here.
 * Capitalization: ALL_CAPS.
 * Note that all macros listed here are limited to this file scope.
 * For project wide scope, declare macros in Eep.h.
 * ----------------------------------------------------------------- @endcond */

/**@cond -----------------------------------------------------------------------
 * Global variables section (File scope)
 * Add global variables with file scope here. 
 * Capitalization: lower_case.
 * Declare them with 'static' keyword.
 * ----------------------------------------------------------------- @endcond */

/**@cond -----------------------------------------------------------------------
 * Global variables section (Project scope)
 * PROJECT SCOPE G-VARIABLES ARE LIKE FORBIDDEN FRUIT. REFRAIN FROM USING THEM, 
 * DECLARE FILE SCOPE G-VARIABLES INSTEAD AND DEFINE GETTER/SETTER METHODS TO 
 * ACCESS THEM.
 * Add global variables with project scope here. 
 * Capitalization: lower_case.
 * Declare them without 'static' keyword.
 * Also declare these variables in Eep.h with 'extern' keyword.
 * ----------------------------------------------------------------- @endcond */

/**@cond -----------------------------------------------------------------------
 * Function prototypes section (File scope)
 * Add prototypes for all functions with file scope here. 
 * Capitalization: lower_Camel_Case.
 * Declare them with 'static' keyword.
 * For functions with project scope, declare the function prototype in 
 * Eep.h without 'static' keyword.
 * ----------------------------------------------------------------- @endcond */

/**@cond -----------------------------------------------------------------------
 * Getter/setter method section (Project scope)
 * Define getter/setter methods to provide project scope global access to file 
 * scope global variables. (AVOID USING THESE IF YOU HAVE THROUGHPUT ISSUES).
 * Capitalization: get_Camel_Case/is_Camel_Case/set_Camel_Case.
 * Declare the prototype for these functions in Eep.h. 
 * ----------------------------------------------------------------- @endcond */

/**@cond ***********************************************************************
 * TODO: Update all comment fields and delete this line.
 * MOD: For functions with project scope, remove 'static' keyword and declare
 * prototype in Eep.h
 * -------------------------------------------------------------------- @endcond
 * @fn          Std_ReturnType function_name(TYPE parameter1, TYPE parameter2)
 * @return      Describe the function's return value here.
 * @param       parameter1 Describe the function's 1st parameter here.
 * @param       parameter2 Describe the function's 2nd parameter here.
 * @author      Ashwin
 * @date        Feb 18, 2012, 7:07:15 PM
 * @brief	Provide a brief description of the module here (Single line).
 * @details	Provide a detailed description of the module here (Multi-line).
 * @pre         Mention any preconditions required to use this function.
 * @post        Mention any postcondition required to use this function.
 * @bug         List any bugs in this module.
 * @note        List any odd modes while using this function.
 * @warning     List any warnings against using the objects of this function.
 *******************************************************************************
 */

Std_ReturnType
Eep_Read(I2c_AddressType I2c_EepAddress, Eep_AddressType EepromAddress,
    uint8* DataBufferPtr, Eep_LengthType Length)
{
  Std_ReturnType retVal = E_NOT_OK;

  /* ---- Dummy write ------------------------------------------------------- */
  /* Wait till I2C bus is free */
  IdleI2C();

  /* Send start command */
  StartI2C();

  /* Send device address with Write command */
  WriteI2C(I2c_EepAddress & ~EEP_READ_WRITE_MSK);

  /* Send data address */
  WriteI2C(EepromAddress);

  /* ---- Actual read operation starts here --------------------------------- */
  /* Send restart command */
  RestartI2C();

  /* Send device address with Write command */
  WriteI2C(I2c_EepAddress | EEP_READ_WRITE_MSK);

  /* Read data stream from SDA */
  getsI2C(DataBufferPtr, Length);

  /* Send Stop command */
  StopI2C();

  /* Do not enable the below if you need to fetch data > 8 bytes by
   * consecutively calling Eep_Read.
   */
#if 0
  /* Terminate string */
  *(DataBufferPtr + Length) = NULL;
#endif

  return (retVal);
}

/** End of function_name ************ Copyright (C) 2012 Afflatus Techtronics */

/**@cond ***********************************************************************
 * TODO: Update all comment fields and delete this line.
 * MOD: For functions with project scope, remove 'static' keyword and declare
 * prototype in Eep.h
 * -------------------------------------------------------------------- @endcond
 * @fn          return_type function_name(TYPE parameter1, TYPE parameter2)
 * @return      Describe the function's return value here.
 * @param       parameter1 Describe the function's 1st parameter here.
 * @param       parameter2 Describe the function's 2nd parameter here.
 * @author      Ashwin
 * @date        Feb 18, 2012, 6:33:16 PM
 * @brief	Provide a brief description of the module here (Single line).
 * @details	Provide a detailed description of the module here (Multi-line).
 * @pre         Mention any preconditions required to use this function.
 * @post        Mention any postcondition required to use this function.
 * @bug         List any bugs in this module.
 * @note        List any odd modes while using this function.
 * @warning     List any warnings against using the objects of this function.
 *******************************************************************************
 */

Std_ReturnType
Eep_Write(I2c_AddressType I2c_EepAddress, Eep_AddressType EepromAddress,
    uint8* DataBufferPtr, Eep_LengthType Length)
{
  Std_ReturnType retVal = E_NOT_OK;
  uint8* DataBufferPtr_Buff;

  if(Length <= EEP_PAGE_WRITE_LENGTH)
    {
      memcpy((void*)DataBufferPtr_Buff, (const void*)DataBufferPtr, Length);

      /* Terminate the source data string with a null character */
      *(DataBufferPtr_Buff + Length) = NULL;

      /* Wait till I2C bus is free */
      IdleI2C();

      /* Send start command */
      StartI2C();

      /* Send device address with Write command */
      WriteI2C(I2c_EepAddress & ~EEP_READ_WRITE_MSK);

      /* Send data address */
      WriteI2C(EepromAddress);

      /* Stream data bytes on SDA line */
      putsI2C(DataBufferPtr_Buff);

      /* Send Stop command */
      StopI2C();

      Delay1KTCYx(50);                                        // Give the slave some time to process

      retVal = E_OK;
    }

  return (retVal);
}

/** End of function_name ************ Copyright (C) 2012 Afflatus Techtronics */

/**@cond ***********************************************************************
 * TODO: Update all comment fields and delete this line.
 * MOD: For functions with project scope, remove 'static' keyword and declare
 * prototype in Eep.h
 * -------------------------------------------------------------------- @endcond
 * @fn          Std_ReturnType function_name(TYPE parameter1, TYPE parameter2)
 * @return      Describe the function's return value here.
 * @param       parameter1 Describe the function's 1st parameter here.
 * @param       parameter2 Describe the function's 2nd parameter here.
 * @author      Ashwin
 * @date        Feb 18, 2012, 9:51:59 PM
 * @brief	Provide a brief description of the module here (Single line).
 * @details	Provide a detailed description of the module here (Multi-line).
 * @pre         Mention any preconditions required to use this function.
 * @post        Mention any postcondition required to use this function.
 * @bug         List any bugs in this module.
 * @note        List any odd modes while using this function.
 * @warning     List any warnings against using the objects of this function.
 *******************************************************************************
 */

Std_ReturnType
Eep_Erase(I2c_AddressType I2c_EepAddress, Eep_AddressType EepromAddress,
    Eep_LengthType Length)
{
  Std_ReturnType retVal = E_NOT_OK;

  uint8* DataBufferPtr;

  memset(DataBufferPtr, 0, Length);

  /* Wait till I2C bus is free */
  IdleI2C();

  /* Send start command */
  StartI2C();

  /* Send device address with Write command */
  WriteI2C(I2c_EepAddress & ~EEP_READ_WRITE_MSK);

  /* Send data address */
  WriteI2C(EepromAddress);

  /* Stream data bytes on SDA line */
  putsI2C(DataBufferPtr);

  /* Send Stop command */
  StopI2C();

  Delay1KTCYx(50);                                        // Give the slave some time to process

  return (retVal);
}

/** End of function_name ************ Copyright (C) 2012 Afflatus Techtronics */

/**@cond ***********************************************************************
 * TODO: Update all comment fields and delete this line.
 * MOD: For functions with project scope, remove 'static' keyword and declare
 * prototype in Eep.h
 * -------------------------------------------------------------------- @endcond
 * @fn          Std_ReturnType function_name(TYPE parameter1, TYPE parameter2)
 * @return      Describe the function's return value here.
 * @param       parameter1 Describe the function's 1st parameter here.
 * @param       parameter2 Describe the function's 2nd parameter here.
 * @author      Ashwin
 * @date        Feb 18, 2012, 9:57:01 PM
 * @brief	Provide a brief description of the module here (Single line).
 * @details	Provide a detailed description of the module here (Multi-line).
 * @pre         Mention any preconditions required to use this function.
 * @post        Mention any postcondition required to use this function.
 * @bug         List any bugs in this module.
 * @note        List any odd modes while using this function.
 * @warning     List any warnings against using the objects of this function.
 *******************************************************************************
 */

Std_ReturnType
Eep_Compare(I2c_AddressType I2c_EepAddress, Eep_AddressType EepromAddress,
    uint8* DataBufferPtr, Eep_LengthType Length)
{
  Std_ReturnType retVal = E_NOT_OK;

  uint8* Eep_DataBufferPtr;

  if(E_OK == (Eep_Read(I2c_EepAddress, EepromAddress, Eep_DataBufferPtr, Length)))
    {
      if(0 == strncmp((char*)Eep_DataBufferPtr, (char*)DataBufferPtr, Length))
        {
          retVal = E_OK;
        }
      /* else not required [if(strncmp(Eep_ ...)] */
    }
  /* else not required [if(E_OK == (Eep_Read ...)] */

  return (retVal);
}

/** End of function_name ************ Copyright (C) 2012 Afflatus Techtronics */

/** END OF FILE ********************* Copyright (C) 2012 Afflatus Techtronics */
